{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-03-19T10:39:38.935186600Z",
     "start_time": "2024-03-19T10:39:35.770147900Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\_distutils_hack\\__init__.py:33: UserWarning: Setuptools is replacing distutils.\n",
      "  warnings.warn(\"Setuptools is replacing distutils.\")\n"
     ]
    }
   ],
   "source": [
    "from paddlenlp import Taskflow\n",
    "# from pdfminer.converter import TextConverter\n",
    "# from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter\n",
    "# from pdfminer.pdfpage import PDFPage\n",
    "# import io\n",
    "from gensim.models import Word2Vec\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import re\n",
    "import os\n",
    "import fitz\n",
    "import tkinter as tk\n",
    "from tkinter import ttk, filedialog\n",
    "from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg\n",
    "\n",
    "from matplotlib import rcParams\n",
    "rcParams['font.family'] = 'SimHei'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Exception in Tkinter callback\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\tkinter\\__init__.py\", line 1921, in __call__\n",
      "    return self.func(*args)\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 34, in <lambda>\n",
      "    scale = ttk.Scale(self.controls_frame, from_=0, to=1, orient=tk.HORIZONTAL, length=100, command=lambda value, idx=i: self.update_weight(value, idx))\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 70, in update_weight\n",
      "    self.plot_radar_chart()\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 55, in plot_radar_chart\n",
      "    weighted_values = [value * weight for value, weight in zip(self.values, self.weights)]\n",
      "AttributeError: 'RadarChartApp' object has no attribute 'values'\n",
      "Exception in Tkinter callback\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\tkinter\\__init__.py\", line 1921, in __call__\n",
      "    return self.func(*args)\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 34, in <lambda>\n",
      "    scale = ttk.Scale(self.controls_frame, from_=0, to=1, orient=tk.HORIZONTAL, length=100, command=lambda value, idx=i: self.update_weight(value, idx))\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 70, in update_weight\n",
      "    self.plot_radar_chart()\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 55, in plot_radar_chart\n",
      "    weighted_values = [value * weight for value, weight in zip(self.values, self.weights)]\n",
      "AttributeError: 'RadarChartApp' object has no attribute 'values'\n",
      "Exception in Tkinter callback\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\tkinter\\__init__.py\", line 1921, in __call__\n",
      "    return self.func(*args)\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 34, in <lambda>\n",
      "    scale = ttk.Scale(self.controls_frame, from_=0, to=1, orient=tk.HORIZONTAL, length=100, command=lambda value, idx=i: self.update_weight(value, idx))\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 70, in update_weight\n",
      "    self.plot_radar_chart()\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 55, in plot_radar_chart\n",
      "    weighted_values = [value * weight for value, weight in zip(self.values, self.weights)]\n",
      "AttributeError: 'RadarChartApp' object has no attribute 'values'\n",
      "Exception in Tkinter callback\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\tkinter\\__init__.py\", line 1921, in __call__\n",
      "    return self.func(*args)\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 34, in <lambda>\n",
      "    scale = ttk.Scale(self.controls_frame, from_=0, to=1, orient=tk.HORIZONTAL, length=100, command=lambda value, idx=i: self.update_weight(value, idx))\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 70, in update_weight\n",
      "    self.plot_radar_chart()\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 55, in plot_radar_chart\n",
      "    weighted_values = [value * weight for value, weight in zip(self.values, self.weights)]\n",
      "AttributeError: 'RadarChartApp' object has no attribute 'values'\n",
      "Exception in Tkinter callback\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\tkinter\\__init__.py\", line 1921, in __call__\n",
      "    return self.func(*args)\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 34, in <lambda>\n",
      "    scale = ttk.Scale(self.controls_frame, from_=0, to=1, orient=tk.HORIZONTAL, length=100, command=lambda value, idx=i: self.update_weight(value, idx))\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 70, in update_weight\n",
      "    self.plot_radar_chart()\n",
      "  File \"C:\\Users\\fuyu\\AppData\\Local\\Temp\\ipykernel_18180\\2546268980.py\", line 55, in plot_radar_chart\n",
      "    weighted_values = [value * weight for value, weight in zip(self.values, self.weights)]\n",
      "AttributeError: 'RadarChartApp' object has no attribute 'values'\n",
      "\u001B[33m[2024-03-19 18:39:45,329] [ WARNING]\u001B[0m - The schema has not been set yet, please set a schema via set_schema(). More details about the setting of schema please refer to https://github.com/PaddlePaddle/PaddleNLP/blob/develop/applications/information_extraction/taskflow_text.md\u001B[0m\n",
      "\u001B[32m[2024-03-19 18:39:49,419] [    INFO]\u001B[0m - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load 'C:\\Users\\fuyu\\.paddlenlp\\taskflow\\information_extraction\\uie-base'.\u001B[0m\n",
      "D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\paddlenlp\\transformers\\tokenizer_utils_base.py:2478: FutureWarning: The `max_seq_len` argument is deprecated and will be removed in a future version, please use `max_length` instead.\n",
      "  warnings.warn(\n",
      "D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\paddlenlp\\transformers\\tokenizer_utils_base.py:1878: FutureWarning: The `pad_to_max_length` argument is deprecated and will be removed in a future version, use `padding=True` or `padding='longest'` to pad to the longest sequence in the batch, or use `padding='max_length'` to pad to a max length. In this case, you can give a specific length with `max_length` (e.g. `max_length=45`) or leave max_length to None to pad to the maximal input size of the model (e.g. 512 for Bert).\n",
      "  warnings.warn(\n",
      "D:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\paddlenlp\\transformers\\tokenizer_utils_base.py:1865: UserWarning: Truncation was not explicitly activated but `max_length` is provided a specific value, please use `truncation=True` to explicitly truncate examples to max length. Defaulting to 'longest_first' truncation strategy. If you encode pairs of sequences (GLUE-style) with the tokenizer you can select this strategy more precisely by providing a specific strategy to `truncation`.\n",
      "  warnings.warn(\n",
      "\n",
      "KeyboardInterrupt\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Error in callback <function flush_figures at 0x000001F934038820> (for post_execute):\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mKeyboardInterrupt\u001B[0m                         Traceback (most recent call last)",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\matplotlib_inline\\backend_inline.py:126\u001B[0m, in \u001B[0;36mflush_figures\u001B[1;34m()\u001B[0m\n\u001B[0;32m    123\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m InlineBackend\u001B[38;5;241m.\u001B[39minstance()\u001B[38;5;241m.\u001B[39mclose_figures:\n\u001B[0;32m    124\u001B[0m     \u001B[38;5;66;03m# ignore the tracking, just draw and close all figures\u001B[39;00m\n\u001B[0;32m    125\u001B[0m     \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m--> 126\u001B[0m         \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mshow\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43;01mTrue\u001B[39;49;00m\u001B[43m)\u001B[49m\n\u001B[0;32m    127\u001B[0m     \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[0;32m    128\u001B[0m         \u001B[38;5;66;03m# safely show traceback if in IPython, else raise\u001B[39;00m\n\u001B[0;32m    129\u001B[0m         ip \u001B[38;5;241m=\u001B[39m get_ipython()\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\matplotlib_inline\\backend_inline.py:90\u001B[0m, in \u001B[0;36mshow\u001B[1;34m(close, block)\u001B[0m\n\u001B[0;32m     88\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m     89\u001B[0m     \u001B[38;5;28;01mfor\u001B[39;00m figure_manager \u001B[38;5;129;01min\u001B[39;00m Gcf\u001B[38;5;241m.\u001B[39mget_all_fig_managers():\n\u001B[1;32m---> 90\u001B[0m         \u001B[43mdisplay\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m     91\u001B[0m \u001B[43m            \u001B[49m\u001B[43mfigure_manager\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcanvas\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfigure\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m     92\u001B[0m \u001B[43m            \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m_fetch_figure_metadata\u001B[49m\u001B[43m(\u001B[49m\u001B[43mfigure_manager\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcanvas\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfigure\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m     93\u001B[0m \u001B[43m        \u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m     94\u001B[0m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[0;32m     95\u001B[0m     show\u001B[38;5;241m.\u001B[39m_to_draw \u001B[38;5;241m=\u001B[39m []\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\IPython\\core\\display_functions.py:298\u001B[0m, in \u001B[0;36mdisplay\u001B[1;34m(include, exclude, metadata, transient, display_id, raw, clear, *objs, **kwargs)\u001B[0m\n\u001B[0;32m    296\u001B[0m     publish_display_data(data\u001B[38;5;241m=\u001B[39mobj, metadata\u001B[38;5;241m=\u001B[39mmetadata, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[0;32m    297\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m--> 298\u001B[0m     format_dict, md_dict \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mformat\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mobj\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43minclude\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43minclude\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mexclude\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mexclude\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    299\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m format_dict:\n\u001B[0;32m    300\u001B[0m         \u001B[38;5;66;03m# nothing to display (e.g. _ipython_display_ took over)\u001B[39;00m\n\u001B[0;32m    301\u001B[0m         \u001B[38;5;28;01mcontinue\u001B[39;00m\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\IPython\\core\\formatters.py:179\u001B[0m, in \u001B[0;36mDisplayFormatter.format\u001B[1;34m(self, obj, include, exclude)\u001B[0m\n\u001B[0;32m    177\u001B[0m md \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m    178\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m--> 179\u001B[0m     data \u001B[38;5;241m=\u001B[39m \u001B[43mformatter\u001B[49m\u001B[43m(\u001B[49m\u001B[43mobj\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    180\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m:\n\u001B[0;32m    181\u001B[0m     \u001B[38;5;66;03m# FIXME: log the exception\u001B[39;00m\n\u001B[0;32m    182\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\decorator.py:232\u001B[0m, in \u001B[0;36mdecorate.<locals>.fun\u001B[1;34m(*args, **kw)\u001B[0m\n\u001B[0;32m    230\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m kwsyntax:\n\u001B[0;32m    231\u001B[0m     args, kw \u001B[38;5;241m=\u001B[39m fix(args, kw, sig)\n\u001B[1;32m--> 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m caller(func, \u001B[38;5;241m*\u001B[39m(extras \u001B[38;5;241m+\u001B[39m args), \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkw)\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\IPython\\core\\formatters.py:223\u001B[0m, in \u001B[0;36mcatch_format_error\u001B[1;34m(method, self, *args, **kwargs)\u001B[0m\n\u001B[0;32m    221\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"show traceback on failed format call\"\"\"\u001B[39;00m\n\u001B[0;32m    222\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m--> 223\u001B[0m     r \u001B[38;5;241m=\u001B[39m method(\u001B[38;5;28mself\u001B[39m, \u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[0;32m    224\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mNotImplementedError\u001B[39;00m:\n\u001B[0;32m    225\u001B[0m     \u001B[38;5;66;03m# don't warn on NotImplementedErrors\u001B[39;00m\n\u001B[0;32m    226\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_check_return(\u001B[38;5;28;01mNone\u001B[39;00m, args[\u001B[38;5;241m0\u001B[39m])\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\IPython\\core\\formatters.py:340\u001B[0m, in \u001B[0;36mBaseFormatter.__call__\u001B[1;34m(self, obj)\u001B[0m\n\u001B[0;32m    338\u001B[0m     \u001B[38;5;28;01mpass\u001B[39;00m\n\u001B[0;32m    339\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m--> 340\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mprinter\u001B[49m\u001B[43m(\u001B[49m\u001B[43mobj\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    341\u001B[0m \u001B[38;5;66;03m# Finally look for special method names\u001B[39;00m\n\u001B[0;32m    342\u001B[0m method \u001B[38;5;241m=\u001B[39m get_real_method(obj, \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mprint_method)\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\IPython\\core\\pylabtools.py:152\u001B[0m, in \u001B[0;36mprint_figure\u001B[1;34m(fig, fmt, bbox_inches, base64, **kwargs)\u001B[0m\n\u001B[0;32m    149\u001B[0m     \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mmatplotlib\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mbackend_bases\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m FigureCanvasBase\n\u001B[0;32m    150\u001B[0m     FigureCanvasBase(fig)\n\u001B[1;32m--> 152\u001B[0m fig\u001B[38;5;241m.\u001B[39mcanvas\u001B[38;5;241m.\u001B[39mprint_figure(bytes_io, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkw)\n\u001B[0;32m    153\u001B[0m data \u001B[38;5;241m=\u001B[39m bytes_io\u001B[38;5;241m.\u001B[39mgetvalue()\n\u001B[0;32m    154\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m fmt \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124msvg\u001B[39m\u001B[38;5;124m'\u001B[39m:\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\matplotlib\\backend_bases.py:2187\u001B[0m, in \u001B[0;36mFigureCanvasBase.print_figure\u001B[1;34m(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)\u001B[0m\n\u001B[0;32m   2183\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m   2184\u001B[0m     \u001B[38;5;66;03m# _get_renderer may change the figure dpi (as vector formats\u001B[39;00m\n\u001B[0;32m   2185\u001B[0m     \u001B[38;5;66;03m# force the figure dpi to 72), so we need to set it again here.\u001B[39;00m\n\u001B[0;32m   2186\u001B[0m     \u001B[38;5;28;01mwith\u001B[39;00m cbook\u001B[38;5;241m.\u001B[39m_setattr_cm(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfigure, dpi\u001B[38;5;241m=\u001B[39mdpi):\n\u001B[1;32m-> 2187\u001B[0m         result \u001B[38;5;241m=\u001B[39m print_method(\n\u001B[0;32m   2188\u001B[0m             filename,\n\u001B[0;32m   2189\u001B[0m             facecolor\u001B[38;5;241m=\u001B[39mfacecolor,\n\u001B[0;32m   2190\u001B[0m             edgecolor\u001B[38;5;241m=\u001B[39medgecolor,\n\u001B[0;32m   2191\u001B[0m             orientation\u001B[38;5;241m=\u001B[39morientation,\n\u001B[0;32m   2192\u001B[0m             bbox_inches_restore\u001B[38;5;241m=\u001B[39m_bbox_inches_restore,\n\u001B[0;32m   2193\u001B[0m             \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[0;32m   2194\u001B[0m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[0;32m   2195\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m bbox_inches \u001B[38;5;129;01mand\u001B[39;00m restore_bbox:\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\matplotlib\\backend_bases.py:2043\u001B[0m, in \u001B[0;36mFigureCanvasBase._switch_canvas_and_return_print_method.<locals>.<lambda>\u001B[1;34m(*args, **kwargs)\u001B[0m\n\u001B[0;32m   2039\u001B[0m     optional_kws \u001B[38;5;241m=\u001B[39m {  \u001B[38;5;66;03m# Passed by print_figure for other renderers.\u001B[39;00m\n\u001B[0;32m   2040\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdpi\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mfacecolor\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124medgecolor\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124morientation\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[0;32m   2041\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mbbox_inches_restore\u001B[39m\u001B[38;5;124m\"\u001B[39m}\n\u001B[0;32m   2042\u001B[0m     skip \u001B[38;5;241m=\u001B[39m optional_kws \u001B[38;5;241m-\u001B[39m {\u001B[38;5;241m*\u001B[39minspect\u001B[38;5;241m.\u001B[39msignature(meth)\u001B[38;5;241m.\u001B[39mparameters}\n\u001B[1;32m-> 2043\u001B[0m     print_method \u001B[38;5;241m=\u001B[39m functools\u001B[38;5;241m.\u001B[39mwraps(meth)(\u001B[38;5;28;01mlambda\u001B[39;00m \u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: meth(\n\u001B[0;32m   2044\u001B[0m         \u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39m{k: v \u001B[38;5;28;01mfor\u001B[39;00m k, v \u001B[38;5;129;01min\u001B[39;00m kwargs\u001B[38;5;241m.\u001B[39mitems() \u001B[38;5;28;01mif\u001B[39;00m k \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m skip}))\n\u001B[0;32m   2045\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:  \u001B[38;5;66;03m# Let third-parties do as they see fit.\u001B[39;00m\n\u001B[0;32m   2046\u001B[0m     print_method \u001B[38;5;241m=\u001B[39m meth\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\matplotlib\\backends\\backend_agg.py:497\u001B[0m, in \u001B[0;36mFigureCanvasAgg.print_png\u001B[1;34m(self, filename_or_obj, metadata, pil_kwargs)\u001B[0m\n\u001B[0;32m    450\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mprint_png\u001B[39m(\u001B[38;5;28mself\u001B[39m, filename_or_obj, \u001B[38;5;241m*\u001B[39m, metadata\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, pil_kwargs\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m):\n\u001B[0;32m    451\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m    452\u001B[0m \u001B[38;5;124;03m    Write the figure to a PNG file.\u001B[39;00m\n\u001B[0;32m    453\u001B[0m \n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m    495\u001B[0m \u001B[38;5;124;03m        *metadata*, including the default 'Software' key.\u001B[39;00m\n\u001B[0;32m    496\u001B[0m \u001B[38;5;124;03m    \"\"\"\u001B[39;00m\n\u001B[1;32m--> 497\u001B[0m     \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_print_pil\u001B[49m\u001B[43m(\u001B[49m\u001B[43mfilename_or_obj\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mpng\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpil_kwargs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\matplotlib\\backends\\backend_agg.py:446\u001B[0m, in \u001B[0;36mFigureCanvasAgg._print_pil\u001B[1;34m(self, filename_or_obj, fmt, pil_kwargs, metadata)\u001B[0m\n\u001B[0;32m    441\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m    442\u001B[0m \u001B[38;5;124;03mDraw the canvas, then save it using `.image.imsave` (to which\u001B[39;00m\n\u001B[0;32m    443\u001B[0m \u001B[38;5;124;03m*pil_kwargs* and *metadata* are forwarded).\u001B[39;00m\n\u001B[0;32m    444\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m    445\u001B[0m FigureCanvasAgg\u001B[38;5;241m.\u001B[39mdraw(\u001B[38;5;28mself\u001B[39m)\n\u001B[1;32m--> 446\u001B[0m \u001B[43mmpl\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mimage\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mimsave\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m    447\u001B[0m \u001B[43m    \u001B[49m\u001B[43mfilename_or_obj\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mbuffer_rgba\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43mformat\u001B[39;49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mfmt\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43morigin\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mupper\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[0;32m    448\u001B[0m \u001B[43m    \u001B[49m\u001B[43mdpi\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfigure\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mdpi\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mmetadata\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpil_kwargs\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mpil_kwargs\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\matplotlib\\image.py:1656\u001B[0m, in \u001B[0;36mimsave\u001B[1;34m(fname, arr, vmin, vmax, cmap, format, origin, dpi, metadata, pil_kwargs)\u001B[0m\n\u001B[0;32m   1654\u001B[0m pil_kwargs\u001B[38;5;241m.\u001B[39msetdefault(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mformat\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;28mformat\u001B[39m)\n\u001B[0;32m   1655\u001B[0m pil_kwargs\u001B[38;5;241m.\u001B[39msetdefault(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdpi\u001B[39m\u001B[38;5;124m\"\u001B[39m, (dpi, dpi))\n\u001B[1;32m-> 1656\u001B[0m image\u001B[38;5;241m.\u001B[39msave(fname, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mpil_kwargs)\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\PIL\\Image.py:2284\u001B[0m, in \u001B[0;36mImage.save\u001B[1;34m(self, fp, format, **params)\u001B[0m\n\u001B[0;32m   2281\u001B[0m     filename \u001B[38;5;241m=\u001B[39m fp\u001B[38;5;241m.\u001B[39mname\n\u001B[0;32m   2283\u001B[0m \u001B[38;5;66;03m# may mutate self!\u001B[39;00m\n\u001B[1;32m-> 2284\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_ensure_mutable\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m   2286\u001B[0m save_all \u001B[38;5;241m=\u001B[39m params\u001B[38;5;241m.\u001B[39mpop(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124msave_all\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[0;32m   2287\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mencoderinfo \u001B[38;5;241m=\u001B[39m params\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\PIL\\Image.py:599\u001B[0m, in \u001B[0;36mImage._ensure_mutable\u001B[1;34m(self)\u001B[0m\n\u001B[0;32m    597\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_ensure_mutable\u001B[39m(\u001B[38;5;28mself\u001B[39m):\n\u001B[0;32m    598\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mreadonly:\n\u001B[1;32m--> 599\u001B[0m         \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_copy\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    600\u001B[0m     \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m    601\u001B[0m         \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mload()\n",
      "File \u001B[1;32mD:\\tools_installed\\anaconda\\envs\\bishe\\lib\\site-packages\\PIL\\Image.py:593\u001B[0m, in \u001B[0;36mImage._copy\u001B[1;34m(self)\u001B[0m\n\u001B[0;32m    591\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_copy\u001B[39m(\u001B[38;5;28mself\u001B[39m):\n\u001B[0;32m    592\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mload()\n\u001B[1;32m--> 593\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mim \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mim\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    594\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mpyaccess \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m    595\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mreadonly \u001B[38;5;241m=\u001B[39m \u001B[38;5;241m0\u001B[39m\n",
      "\u001B[1;31mKeyboardInterrupt\u001B[0m: "
     ]
    }
   ],
   "source": [
    "class RadarChartApp:\n",
    "    def __init__(self, root):\n",
    "        self.root = root\n",
    "        self.root.title(\"智能简历挑选器\")\n",
    "        self.root.geometry(\"800x600\")\n",
    "        self.categories = [\"项目经历\", \"教育背景与经历\", \"专业技能与能力\", \"个人特质\", \"奖项与荣誉\"]\n",
    "        self.weights = [1.0] * len(self.categories)\n",
    "        self.main_frame = ttk.Frame(self.root)\n",
    "        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)\n",
    "        self.create_widgets()\n",
    "\n",
    "    def create_widgets(self):\n",
    "        # 左侧雷达图区域\n",
    "        self.radar_frame = ttk.Frame(self.main_frame)\n",
    "\n",
    "        self.fig, self.ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))\n",
    "        self.canvas = FigureCanvasTkAgg(self.fig, master=self.radar_frame)\n",
    "        self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)\n",
    "\n",
    "        # 右侧控制区域\n",
    "        self.controls_frame = ttk.Frame(self.main_frame)\n",
    "        self.controls_frame.pack(side=tk.RIGHT, padx=20)\n",
    "\n",
    "        self.file_button = ttk.Button(self.controls_frame, text=\"上传PDF简历\", command=self.open_pdf_file)\n",
    "        self.file_button.pack()\n",
    "\n",
    "        self.file_label = ttk.Label(self.controls_frame, text=\"\")\n",
    "        self.file_label.pack(pady=5)\n",
    "\n",
    "        self.weight_scales = []\n",
    "        for i, category in enumerate(self.categories):\n",
    "            scale_label = ttk.Label(self.controls_frame, text=category)\n",
    "            scale_label.pack()\n",
    "            scale = ttk.Scale(self.controls_frame, from_=0, to=1, orient=tk.HORIZONTAL, length=100, command=lambda value, idx=i: self.update_weight(value, idx))\n",
    "            scale.set(1.0)\n",
    "            scale.pack()\n",
    "            self.weight_scales.append(scale)\n",
    "\n",
    "    def open_pdf_file(self):\n",
    "        file_path = filedialog.askopenfilename(filetypes=[(\"PDF Files\", \"*.pdf\")])\n",
    "        if file_path:\n",
    "            self.file_label.config(text=os.path.basename(file_path))\n",
    "            self.process_pdf(file_path)\n",
    "\n",
    "    def process_pdf(self, file_path):\n",
    "        self.values = IntelligentResumePicker(file_path).run()\n",
    "        self.plot_radar_chart()\n",
    "\n",
    "    def plot_radar_chart(self, *_):\n",
    "        self.ax.clear()\n",
    "        N = len(self.categories)\n",
    "        angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()  # 计算角度\n",
    "        angles += angles[:1]  # 闭合图形\n",
    "\n",
    "        weighted_values = [value * weight for value, weight in zip(self.values, self.weights)]\n",
    "        weighted_values += weighted_values[:1]  # 闭合图形\n",
    "\n",
    "        self.ax.plot(angles, weighted_values, linewidth=1, linestyle='solid', label=\"实际值\")\n",
    "        self.ax.fill(angles, weighted_values, 'b', alpha=0.1)\n",
    "\n",
    "        self.ax.set_theta_offset(np.pi / 2)  # 调整角度偏移\n",
    "        self.ax.set_theta_direction(-1)  # 调整角度方向\n",
    "        self.ax.set_xticks(angles[:-1])\n",
    "        self.ax.set_xticklabels(self.categories, color='black', size=10)\n",
    "        self.canvas.draw()\n",
    "        self.radar_frame.pack(side=tk.LEFT)\n",
    "\n",
    "    def update_weight(self, value, idx):\n",
    "        self.weights[idx] = float(value)\n",
    "        self.plot_radar_chart()\n",
    "\n",
    "\n",
    "class IntelligentResumePicker:\n",
    "    def __init__(self, file_path):\n",
    "        self.text = None\n",
    "        self.ner_nlp = Taskflow('information_extraction')\n",
    "        self.ner_nlp1 = Taskflow('ner')\n",
    "        self.file_path = file_path\n",
    "        self.model = Word2Vec.load(\"../Data/word2vec model/zh_to_vec.model\")\n",
    "        self.stop_word = open(\"../Data/stop_words.txt\", encoding='utf-8').read().split(\"\\n\")\n",
    "\n",
    "    @staticmethod\n",
    "    def zh_replace_special_char(cleaned_text):\n",
    "        \"\"\"\n",
    "        去除特殊字符\n",
    "        :param cleaned_text:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        # 去掉一些特殊字符\n",
    "        cleaned_text = re.sub(\"\\s+\", \" \", cleaned_text)\n",
    "        return cleaned_text\n",
    "\n",
    "    def extract_text_from_pdf(self):\n",
    "        doc = fitz.open(self.file_path)\n",
    "        texts = \"\"\n",
    "        for index in range(doc.page_count):\n",
    "            page1 = doc.load_page(index)\n",
    "            texts += page1.get_text(\"text\")\n",
    "\n",
    "        # resource_manager = PDFResourceManager()\n",
    "        # fake_file_handle = io.StringIO()\n",
    "        # converter = TextConverter(resource_manager, fake_file_handle)\n",
    "        # page_interpreter = PDFPageInterpreter(resource_manager, converter)\n",
    "        # with open(self.file_path, 'rb') as fh:\n",
    "        #     for page in PDFPage.get_pages(fh, caching=True, check_extractable=True):\n",
    "        #         page_interpreter.process_page(page)\n",
    "        #     texts = fake_file_handle.getvalue()\n",
    "        # converter.close()\n",
    "        # fake_file_handle.close()\n",
    "        if texts:\n",
    "            self.text = texts\n",
    "            return texts\n",
    "\n",
    "    def get_key_word(self):\n",
    "        if '实习经历' in self.text:\n",
    "            resume_criteria = [\"实习经历\", \"教育背景\", \"个人能力\", \"个人特质\", \"奖项与荣誉\"]\n",
    "        else:\n",
    "            resume_criteria = [\"项目经历\", \"教育背景\", \"专业技能\", \"个人特质\", \"奖项与荣誉\"]\n",
    "        self.ner_nlp.set_schema(resume_criteria)\n",
    "        doc = self.ner_nlp(self.text)\n",
    "        # 对每个key对应的value根据probability值进行排序，并选取probability值最高的内容\n",
    "        sorted_data = {}\n",
    "        for key, values in doc[0].items():\n",
    "            sorted_values = sorted(values, key=lambda x: x['probability'], reverse=True)\n",
    "            sorted_data[key] = sorted_values[0]['text']\n",
    "\n",
    "        project_experience = []\n",
    "        education_background = []\n",
    "        professional_skills = []\n",
    "        personal_traits = []\n",
    "        awards_honors = []\n",
    "\n",
    "        # 遍历命名实体，根据标签分类\n",
    "        for entity, label in self.ner_nlp1(self.text):\n",
    "            if entity in self.stop_word or len(entity.strip()) < 2:\n",
    "                continue\n",
    "            # 项目经历\n",
    "            entity = entity.strip()\n",
    "            if '作品类' in label and label == \"作品类_实体\":\n",
    "                project_experience.append(entity)\n",
    "            # 教育背景与经历\n",
    "            elif '组织机构类' in label or ('术语类' in label and '课程' in entity):\n",
    "                education_background.append(entity)\n",
    "            # 专业技能与能力\n",
    "            elif ('术语类' in label and \"术语类_符号指标类\" != label) or '作品类' in label or '场景事件' in label:\n",
    "                professional_skills.append(entity)\n",
    "            # 个人特质\n",
    "            elif '个性特征' in label:\n",
    "                personal_traits.append(entity)\n",
    "            # 奖项与荣誉\n",
    "            elif '奖项' in label or '荣誉' in label:\n",
    "                awards_honors.append(entity)\n",
    "\n",
    "        if sorted_data.get(\"教育背景\"):\n",
    "            education_background.append(sorted_data['教育背景'])\n",
    "\n",
    "        # print(\"项目经历：\", project_experience)\n",
    "        # print(\"教育背景：\", education_background)\n",
    "        # print(\"专业技能：\", professional_skills)\n",
    "        # print(\"个人特质：\", personal_traits)\n",
    "        # print(\"奖项与荣誉：\", awards_honors)\n",
    "        return [project_experience, education_background, professional_skills, personal_traits, awards_honors]\n",
    "\n",
    "    # 计算相似度评分\n",
    "    def calculate_similarity_score(self, entity_list, label):\n",
    "        def utils():\n",
    "            if label == \"教育背景与经历\":\n",
    "                return len(entity_list[0]) * 0.1 if len(entity_list[0]) < 10 else 0.85\n",
    "            else:\n",
    "                return len(entity_list[0]) * 0.07 if len(entity_list[0]) < 10 else 0.75\n",
    "\n",
    "        scores = []\n",
    "        for entities in entity_list:\n",
    "            entity_scores = []\n",
    "            for entity in entities:\n",
    "                if entity in self.model.wv:\n",
    "                    # 获取与实体词最相似的词向量\n",
    "                    most_similar = self.model.wv.most_similar(entity, topn=1)\n",
    "                    # 提取相似度\n",
    "                    similarity = most_similar[0][1] if most_similar else 0\n",
    "                    if similarity > 0:\n",
    "                        entity_scores.append(similarity)\n",
    "            if entity_scores:\n",
    "                avg_score = np.mean(entity_scores)\n",
    "                scores.append(avg_score)\n",
    "        return np.mean(scores) if scores else utils()\n",
    "\n",
    "    def run(self):\n",
    "        self.extract_text_from_pdf()\n",
    "        self.text = self.zh_replace_special_char(self.text)\n",
    "        data = self.get_key_word()\n",
    "        # 计算每个实体列表的相似度评分\n",
    "        name_title = [\"项目经历\", \"教育背景与经历\", \"专业技能与能力\", \"个人特质\", \"奖项与荣誉\"]\n",
    "        data = [self.calculate_similarity_score([entities], label) for label, entities in zip(name_title, data)]\n",
    "        return data\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    root = tk.Tk()\n",
    "    app = RadarChartApp(root)\n",
    "    root.mainloop()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-19T10:40:37.451755Z",
     "start_time": "2024-03-19T10:39:38.951630100Z"
    }
   },
   "id": "6551f1bb9a176bb"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
